home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static char *SCCSid = "%W% (NCSA) %G%";
- #endif lint
-
- /*
- ** Raster Virtual Kernel
- */
-
- #define RASTER_MASTER
- #define MASTERDEF
-
- #include <stdio.h>
- #include <string.h>
-
- #include <Memory.h>
-
- #include "rr.h"
- #include "vr.h"
- #include "RGrout.h"
- #include "rasmac.h"
-
- /*
- ** global vars
- */
-
- static int VRstate = DONE; /* current state */
- static int VRcmdnum = -1; /* current command */
- static int VRargcount = 0; /* number of args for command */
- static int VRdatalen = 0; /* length of expected data */
- static int VRbufpos = 0; /* current pointer in tempdata */
- static union arg VRargs[MAXARGS]; /* argument vector */
- static char VRtempdata[256]; /* temporary storage while parsing */
- static char *VRspace; /* storage for incoming data */
- static char *VRsp2; /* storage for pixel expansion */
- static char *VRptr; /* pointer for data buffer */
- static char *VRptr2; /* copy of above */
-
- /***********************************************************************/
- /* decode0 and decode1
- * start and continue the decoding.
- *
- * Returns real characters, 0 if in the middle of an escape sequence.
- */
-
- #define FRSKIP 0
- #define FRIN 1
- #define FRSPECIAL 2
- #define FROVER 3
- #define FRDONE 4
-
- static int dstate=FRSKIP,dspec=0;
- /*
- * set up receive
- */
- void decode0
- (
- void
- )
- {
- dstate = FRIN;
- }
-
- decode1(c)
- int c;
- {
- switch (dstate) {
- case FRSKIP:
- return(-1);
-
- case FRIN: /* decoding */
- if (c > 31 && c < 123)
- return(c);
- else {
- dspec = c; /* save special character */
- dstate = FRSPECIAL; /* doing special character */
- }
- return(-1);
- case FRSPECIAL:
- switch (dspec) {
- case 123:
- case 124:
- case 125:
- case 126: /* encoded character */
- dstate = FRIN;
- return(((dspec - 123)<< 6) - 32 + c);
- default: /* mistaken character in stream */
- dstate = FRIN; /* assume not special */
- return(decode1(c)); /* check for sure */
- break;
- }
- break;
-
- }
-
- }
-
- /*
- ** VRinit -- initialize the VR system
- **
- ** Arguments:
- **
- ** None.
- **
- ** Returns:
- **
- ** int -- status, 1 == succsessful, 0 == failed
- */
-
- int VRinit
- (
- void
- )
- {
- VRhead.w_next = NULL;
- VRsp2 = (char *)NewPtr(4*LINEMAX+10);
- VRspace = (char *)NewPtr(LINEMAX+10);
- if (VRspace)
- return 1;
- else
- return 0;
- }
-
- /*
- ** VRwrite -- parse a string of VR commands
- **
- ** Arguments:
- **
- ** char *b; -- buffer pointer
- ** int len; -- buffer length
- **
- ** Returns:
- **
- ** int -- Number of characters processed. 0 tells
- ** -- the upper level to switch out of raster mode;
- ** -- usually on error, but also at completion of
- ** -- command processing.
- **
- */
-
- int VRwrite
- (
- char *b,
- int len
- )
- {
-
- int count = 0;
- char *p = b;
- char c;
- int i;
- extern char *strcpy();
- int VRnextargstate();
-
- /*
- ** loop 'til no more chars
- */
-
- while (count < len) {
- c = *p;
-
- switch (VRstate) {
- case DONE:
-
- if (c == ESC)
- VRstate = ESCFOUND;
- else
- return count;
- break;
-
- case ESCFOUND:
-
- if (c == CMDTRM)
- VRstate = WANTCMD;
- else {
- VRstate = DONE;
- return count;
- }
- break;
-
- /*
- ** looking for a valid command char
- */
-
- case WANTCMD:
-
- for (i = 0; i < NCMDS; i++) {
- if (cmdtab[i].c_name == c)
- break;
- }
-
- VRcmdnum = i;
-
- /*
- ** not a valid command, so later
- */
-
- if (VRcmdnum == NCMDS) {
- VRstate = DONE;
- return 0;
- }
-
- /*
- ** set up for this command
- */
-
- VRargcount = 0;
- VRbufpos = 0;
-
- VRstate = WANTDEL;
- break;
-
- /*
- ** look for that first ;
- */
-
- case WANTDEL:
- if (c == DELIM)
- VRstate = VRnextargstate(VRargcount, VRcmdnum);
- else {
- VRstate = DONE;
- }
- break;
-
- /*
- ** looking for an integer arg
- */
-
- case IARG:
- switch (c) {
-
- /*
- ** we've found the end of the argument, so
- ** try to put into the vector for later use
- */
-
- case DELIM:
- case CMDTRM:
- VRtempdata[VRbufpos] = '\0';
-
- /*
- ** copy into argument union
- */
-
- (void)sscanf(VRtempdata,"%d",&VRargs[VRargcount].a_num);
- VRbufpos = 0;
-
- VRargcount++;
- if (c == DELIM)
- VRstate = VRnextargstate(VRargcount, VRcmdnum);
- else
- if (cmdtab[VRcmdnum].c_flags & FL_DATA)
- VRstate = DATA;
- else {
-
- /*
- ** run the command
- */
-
- (*cmdtab[VRcmdnum].c_func)(VRargs, (char *)0L);
- VRstate = DONE;
- }
-
- break;
-
- /*
- ** copy over characters for later
- */
-
- default:
- VRtempdata[VRbufpos++] = c;
- }
- break;
-
- /*
- ** looking for string arg
- */
-
- case SARG:
- switch (c) {
-
- /*
- ** put string into argument vector
- */
-
- case DELIM:
- case CMDTRM:
-
- VRtempdata[VRbufpos] = '\0';
- /*
- VRargs[VRargcount].a_ptr = NewPtr((unsigned)VRbufpos+1);
-
- if (VRargs[VRargcount].a_ptr == (char *)0L) {
- VRstate = DONE;
- break;
- }
- */
-
- (void)strcpy(VRargs[VRargcount].a_ptr, VRtempdata);
- VRbufpos = 0;
- VRargcount++;
- if (c == DELIM)
- VRstate = VRnextargstate(VRargcount, VRcmdnum);
- else
- if (cmdtab[VRcmdnum].c_flags & FL_DATA)
- VRstate = DATA;
- else {
-
- /*
- ** run the command
- */
-
- (*cmdtab[VRcmdnum].c_func)(VRargs, (char *)0L);
- VRstate = DONE;
- }
-
- break;
-
- /*
- ** save string for later
- */
-
- default:
- VRtempdata[VRbufpos++] = c;
-
- }
- break;
-
- /*
- ** looking for a count argument
- */
-
- case CARG:
- switch (c) {
-
- /*
- ** we've found the end of the argument, so
- ** try to put into the vector for later use
- */
-
- case DELIM:
- case CMDTRM:
- VRtempdata[VRbufpos] = '\0';
-
- /*
- ** copy into argument union
- */
-
- (void)sscanf(VRtempdata,"%d",&VRdatalen);
- (void)sscanf(VRtempdata,"%d",&VRargs[VRargcount].a_num);
- if (VRdatalen > LINEMAX)
- VRdatalen = LINEMAX;
- VRargcount++;
- VRbufpos = 0;
-
- if (c == DELIM)
- VRstate = VRnextargstate(VRargcount, VRcmdnum);
- else
- if (cmdtab[VRcmdnum].c_flags & FL_DATA)
- VRstate = DATA;
- else {
-
- /*
- ** run the command
- */
-
- (*cmdtab[VRcmdnum].c_func)(VRargs, (char *)0L);
- VRstate = DONE;
- }
-
- /*
- ** allocate storage for data
- */
-
- VRptr = VRspace;
-
- if (VRptr == (char *)0L) {
- VRstate = DONE;
- return 0;
- }
- VRptr2 = VRptr;
- decode0(); /* reset decoder */
-
- break;
-
- /*
- ** copy over characters for later
- */
-
- default:
- VRtempdata[VRbufpos++] = c;
- }
- break;
-
- /*
- ** retrieve a line of data
- */
-
- case DATA:
-
- /*
- ** store bytes until done
- */
-
- if (0 <= (i = decode1(c))) {
- *VRptr2++ = i;
- --VRdatalen;
- }
-
- if (!VRdatalen) {
-
- /*
- ** we've got all of the data
- */
-
- (*cmdtab[VRcmdnum].c_func)(VRargs, VRptr);
- VRstate = DONE;
- }
-
- break;
-
- } /* end switch(VRstate)*/
-
- p++;
- count++;
- } /* end while loop */
-
- return count;
- }
-
- /*
- ** VRnextargstate -- return the next state based on where we're
- ** -- at already.
- **
- ** Arguments:
- **
- ** int ac -- current argument count
- ** int state -- current state
- ** int c -- current command
- **
- ** Returns:
- **
- ** int -- next state to move to
- **
- */
-
- static int VRnextargstate(ac, c)
- int ac;
- int c;
- {
-
- switch (cmdtab[c].c_args[ac]) {
- case INT:
- return IARG;
- case STRING:
- return SARG;
- case COUNT:
- return CARG;
- case 0:
- return DATA;
-
- /*
- ** in case of error
- */
-
- default:
- return DONE;
- }
- }
-
- /*
- ** VRwindow -- create a new raster window
- **
- ** Arguments:
- **
- ** union arg av[]; -- the argument vector
- **
- ** int av[0, 1]; -- upper left;
- ** int av[2, 3]; -- width, height
- ** int av[4]; -- window hardware display number
- ** char *av[5]; -- title
- **
- ** Returns:
- **
- ** None. No provision has been made for error returns in any of
- ** these routines because I don't know what to do if an error
- ** occurs. Perhaps a better man than I can figure out how to
- ** deal with this.
- ** N.B -- these functions are declared as int, in the event
- ** that an error return is added.
- */
-
- int VRwindow(av)
- union arg av[];
- {
-
- VRW *w = VRhead.w_next;
-
- /*
- ** search list, and if needed, NewPtr some space for a new window thing
- */
-
- while (w) {
- if (!strcmp(w->w_name,av[5].a_ptr)
- && w->w_width == av[2].a_num
- && w->w_height == av[3].a_num) /* don't re-allocate win */
- return(1);
- if (!strcmp(w->w_name,av[5].a_ptr)) /* duplicate, different size */
- w->w_used = 1;
- w = w->w_next;
- }
-
- w = (VRW *)NewPtr(sizeof(VRW)); /* new element for list */
- if (!w)
- return(-1);
-
- w->w_next = VRhead.w_next; /* set next equal to current head */
- VRhead.w_next = w; /* set head of list equal to me */
-
- /*
- ** fill in the new window area
- */
-
- w->w_left = av[0].a_num;
- w->w_top = av[1].a_num;
- w->w_width = av[2].a_num;
- w->w_height = av[3].a_num;
- w->w_display = av[4].a_num;
- w->w_used = 0;
- strncpy(w->w_name,av[5].a_ptr,100);
-
- if (w->w_width > LINEMAX) /* have to be SOME limits */
- w->w_width = LINEMAX;
-
- return RasWindow(w);
- }
-
- /*
- ** VRdestroy -- destroy a window by name
- **
- ** Arguments:
- **
- ** union arg av[]; -- the argument vector
- **
- ** char *av[0] -- the name of the window
- **
- ** Returns:
- **
- ** None.
- **
- */
-
- int VRdestroy
- (
- union arg av[]
- )
- {
- VRW *w,*ow;
- extern int strcmp();
-
- ow = &VRhead;
- w = ow->w_next;
-
- while (w) {
- if (!strcmp(w->w_name, av[0].a_ptr)) {
- RasDestroy(w);
- ow->w_next = w->w_next;
- DisposPtr((char *)w);
- }
- else
- ow = ow->w_next;
-
- w = ow->w_next;
- }
-
- return 0;
- }
-
- /*
- ** VRmap -- take a color map command and set the palette
- **
- ** Arguments:
- **
- ** union arg av[]; -- the argument vector
- **
- ** int av[0, 1]; -- start & length of map segment
- ** int av[2]; -- count of data needed (info only)
- ** char *av[3]; -- window name
- ** char *data; -- pointer to the data
- **
- ** Returns:
- **
- ** None.
- **
- */
-
- int VRmap(av,data)
- union arg av[];
- char *data;
- {
- VRW *w;
- VRW *VRlookup();
-
- w = VRlookup(av[3].a_ptr);
-
- if (!w)
- return 0;
-
- return (*RGmap)(av[0].a_num, av[1].a_num, data);
- }
-
- /*
- ** VRpixel -- display a line of pixel data
- **
- ** Arugments:
- **
- ** union arg av[]; -- the argument vector
- **
- ** int av[0]; -- x coordinate
- ** int av[1]; -- y coordinate
- ** int av[2]; -- pixel expansion factor
- ** int av[3]; -- length of data
- ** char *av[4]; -- window name
- ** char *data; -- pointer to data
- **
- ** Returns:
- **
- ** None.
- **
- */
-
- int VRpixel(av, data)
- union arg av[];
- char *data;
- {
- VRW *w;
- VRW *VRlookup();
- int i,lim;
- char *p,*q;
-
- /*
- ** find the right window
- */
-
- w = VRlookup(av[4].a_ptr);
-
- if (w == (VRW *)0L)
- return 0;
-
- lim = av[3].a_num*av[2].a_num; /* total number of expanded pixels */
- if (lim > w->w_width)
- lim = w->w_width;
-
- if (av[2].a_num > 1) {
- p = data;
- q = VRsp2;
- for (i=0; i < lim; i++) {
- *q++ = *p;
- if (!((i+1) % av[2].a_num))
- p++;
- }
- for (i=0; i<av[2].a_num; i++)
- (*RGraster)( VRsp2, av[0].a_num, av[1].a_num+i,
- av[0].a_num+lim, av[1].a_num+i,lim);
-
- }
- else
- return (*RGraster)( data, av[0].a_num, av[1].a_num,
- av[0].a_num+av[3].a_num, av[1].a_num,lim);
-
- return 0;
- }
-
- /*
- ** VRimp -- display a line of IMPCOMP encoded data
- ** One line of IMPCOMP data gives 4 lines output.
- **
- ** Arugments:
- **
- ** union arg av[]; -- the argument vector
- **
- ** int av[0]; -- x coordinate
- ** int av[1]; -- y coordinate
- ** int av[2]; -- pixel expansion
- ** int av[3]; -- length of data
- ** char *av[4]; -- window name
- ** char *data; -- pointer to data
- **
- ** Returns:
- **
- ** None.
- **
- */
-
- void unimcomp();
-
- int VRimp(av, data)
- union arg av[];
- char *data;
- {
- VRW *w;
- VRW *VRlookup();
- int i,lim,j;
- char *p,*q;
-
- /*
- ** find the right window
- */
-
- w = VRlookup(av[4].a_ptr);
-
- if (w == (VRW *)0L)
- return 0;
-
- unimcomp(data,VRsp2,av[3].a_num,w->w_width); /* decompress it */
- /* gives four lines in the VRsp2 buffer, now pixel expand */
-
- i = av[3].a_num;
-
- lim = i*av[2].a_num; /* total number of expanded pixels on a line*/
- if (lim > w->w_width)
- lim = w->w_width;
- if (i > w->w_width)
- i = w->w_width;
-
- p = VRsp2; /* from this buffer */
- for (j=0; j<4; j++) {
- if (av[2].a_num > 1) {
- q = VRspace; /* to here */
- for (i=0; i < lim; i++) {
- *q++ = *p;
- if (!((i+1) % av[2].a_num))
- p++;
- }
- p++;
- for (i=0; i<av[2].a_num; i++)
- (*RGraster)(VRspace, av[0].a_num, av[1].a_num+i+j*av[2].a_num,
- av[0].a_num + av[3].a_num, av[1].a_num+i+j*av[2].a_num, lim );
-
- }
- else {
- (*RGraster)(p, av[0].a_num, av[1].a_num+j,
- av[0].a_num + av[3].a_num, av[1].a_num+j, i);
- p += av[3].a_num; /* increment to next line */
- }
-
- }
-
- return 0;
-
- }
-
- /************************************************************************/
- /* Function : unimcomp */
- /* Purpose : 'Decompresses' the compressed image */
- /* Parameter : */
- /* xdim - x dimensions of image */
- /* lines - number of lines of compressed image */
- /* in, out - Input buffer and output buffer. Size of input buffer */
- /* is xdim*lines. Size of output buffer is 4 times */
- /* that. It 'restores' images into seq-type files */
- /* Returns : none */
- /* Called by : External routines */
- /* Calls : none */
- /************************************************************************/
-
- void unimcomp(in, out, xdim, xmax)
- int xdim, xmax;
- unsigned char in[], out[];
- {
- int bitmap, temp, lines=1;
- register int i, j, k, x;
- unsigned char hi_color, lo_color;
-
- if (xmax < xdim) /* don't go over */
- xdim = xmax;
-
- /* go over the compressed image */
- for (x=0; x<xdim; x=x+4)
- {
- k = x;
- hi_color = in[k+2];
- lo_color = in[k+3];
-
- bitmap = (in[k] << 8) | in[k+1];
-
- /* store in out buffer */
- for (i=0; i<4; i++)
- {
- temp = bitmap >> (3 - i)*4;
- for (j=x; j<(x+4); j++)
- {
- if ((temp & 8) == 8)
- out[i*xdim+j] = hi_color;
- else
- out[i*xdim+j] = lo_color;
- temp = temp << 1;
- }
- }
- } /* end of for x */
- } /* end of unimcomp */
-
- /*****************************************************************/
- /* unrleit
- * Decompress run length encoding.
- *
- */
-
- int unrleit
- (
- unsigned char *buf,
- unsigned char *bufto,
- int inlen,
- int outlen
- )
- {
- register int cnt;
- register unsigned char *p,*q;
- unsigned char *endp,*endq;
-
- p = buf;
- endp = buf + inlen;
- q = bufto;
- endq = bufto + outlen;
- while (p < endp && q < endq) /* go 'til p or q hits end */
- {
- cnt = *p++; /* count field */
- if (!(cnt & 128))/* is set of uniques */
- {
- while (cnt-- && q < endq)
- *q++ = *p++; /* copy unmodified */
- }
- else
- {
- cnt &= 127; /* strip high bit */
- while (cnt-- && q < endq)
- *q++ = *p; /* copy same character */
- p++; /* skip that character */
- } /* if */
- } /* while */
- return((int)(q-bufto));
- } /* unrleit */
-
- /***************************************************************************/
- /*
- ** VRrle -- display a line of run-length encoded data
- **
- ** Arugments:
- **
- ** union arg av[]; -- the argument vector
- **
- ** int av[0]; -- x coordinate
- ** int av[1]; -- y coordinate
- ** int av[2]; -- pixel expansion
- ** int av[3]; -- length of data
- ** char *av[4]; -- window name
- ** char *data; -- pointer to data
- **
- ** Returns:
- **
- ** None.
- **
- */
-
- int VRrle(av, data)
- union arg av[];
- char *data;
- {
- VRW *w;
- VRW *VRlookup();
- int i,lim;
- char *p,*q;
-
- /*
- ** find the right window
- */
-
- w = VRlookup(av[4].a_ptr);
-
- if (w == (VRW *)0L)
- return 0;
-
- i = unrleit(data,VRsp2,av[3].a_num,w->w_width); /* decompress it */
-
-
- lim = i*av[2].a_num; /* total number of expanded pixels */
- if (lim > w->w_width)
- lim = w->w_width;
-
- if (av[2].a_num > 1) {
- p = VRsp2; /* from this buffer */
- q = VRspace; /* to here */
- for (i=0; i < lim; i++) {
- *q++ = *p;
- if (!((i+1) % av[2].a_num))
- p++;
- }
- for (i=0; i<av[2].a_num; i++)
- (*RGraster)( VRspace, av[0].a_num, av[1].a_num+i,
- av[0].a_num+lim, av[1].a_num+i,lim);
-
- }
- else
- return (*RGraster)( VRsp2, av[0].a_num, av[1].a_num,
- av[0].a_num+i, av[1].a_num,i);
-
- return 0;
-
- }
-
- /*
- ** VRfile -- cause the named window to be dumped to a file
- **
- ** Arguments:
- **
- ** union arg av[]; -- the argument vector
- **
- ** int av[0]; -- start x coordinate
- ** int av[1]; -- start y coordinate
- ** int av[2]; -- width of region to dump
- ** int av[3]; -- height of region to dump
- ** int av[4]; -- format of file -- machine dependent
- ** char *av[5]; -- file name to use
- ** char *av[6]; -- window name to dump
- **
- ** Returns:
- **
- ** int; -- 1 if success, 0 if failure
- **
- */
-
- int VRfile(av)
- union arg av[];
- {
- #ifdef IMPLEMENTED
- VRW *w;
- VRW *VRlookup();
-
- /*
- ** Look up the window
- */
-
- w = VRlookup(av[6].a_ptr);
-
- if (w == (VRW *)0L)
- return 0;
-
- /*
- ** call the low level file routine
- */
-
- return RRfile(w, av[0].a_num, av[1].a_num, av[2].a_num, av[3].a_num,
- av[4].a_num, av[5].a_ptr);
- #else IMPLEMENTED
- #pragma unused(av)
- return 0;
- #endif IMPLEMENTED
- }
-
- /*
- ** VRclick -- Click the Slide Camera -- very machine dependent
- **
- ** Arguments:
- **
- ** union arg av[]; -- the argument vector
- **
- ** char *av[0]; -- window name
- **
- ** Returns:
- **
- ** int; -- 1 if success, 0 if failure
- */
-
- int VRclick(av)
- union arg av[];
- {
- #ifdef IMPLEMENTED
- VRW *w;
- VRW *VRlookup();
-
- /*
- ** look up the window
- */
-
- w = VRlookup(av[0].a_ptr);
-
- if (w == (VRW *)0L)
- return 0;
-
- return RRclick(w);
- #else IMPLEMENTED
- #pragma unused(av)
- return 0;
- #endif IMPLEMENTED
- }
-
- /*
- ** VRmsave -- Save the named colormap to the file -- saves the whole thing
- **
- ** Arguments:
- **
- ** union arg av[]; -- the argument vector
- **
- ** char *av[0]; -- file name
- ** char *av[1]; -- window name
- **
- ** Returns:
- **
- ** int; -- 1 if success, 0 if failure
- */
-
- int VRmsave(av)
- union arg av[];
- {
- #ifdef IMPLEMENTED
- VRW *w;
- VRW *VRlookup();
-
- /*
- ** look up the window
- */
-
- w = VRlookup(av[1].a_ptr);
-
- if (w == (VRW *)0L)
- return 0;
-
- return RRmsave(w, av[0].a_ptr);
- #else IMPLEMENTED
- #pragma unused(av)
- return 0;
- #endif IMPLEMENTED
- }
-
- /*
- ** VRlookup -- find an entry in the list by name
- **
- ** Arguments:
- **
- ** char *name; -- the name of the window
- **
- ** Returns:
- **
- ** VRW *w; -- pointer to window structure, (VRW *)0 if not found
- **
- */
-
- VRW *VRlookup(name)
- char *name;
- {
- VRW *w = VRhead.w_next;
-
- while (w) {
- if (!strcmp(w->w_name, name) && !w->w_used) { /* same name, not old dup */
- if (RasSetwind(w)) /* maybe window don't work */
- return(NULL);
- return(w);
- }
- w = w->w_next;
- }
-
- return(NULL);
- }
-
- /*
- ** VRcleanup -- remove all windows from the screen
- **
- ** Arguments:
- **
- ** None.
- **
- ** Returns:
- **
- ** int; 1 -- always successful, or there's nothing you can do
- ** -- about it anyways...
- **
- */
-
- int VRcleanup()
- {
- VRW *w = VRhead.w_next;
- VRW *x;
-
- while (w != (VRW *)0L) {
- x = w->w_next;
- RasDestroy(w);
- w = x;
- }
-
- return 1;
- }
-
- /************************************************************************/
- /* decoding
- * handle the special ASCII printable character encoding of data bytes.
- */
-
- /***********************************************************************/
- /*
- * 123 precedes #'s 0-63
- * 124 precedes #'s 64-127
- * 125 precedes #'s 128-191
- * 126 precedes #'s 192-255
- * overall: realchar = (specialchar - 123)*64 + (char-32)
- * specialchar = r div 64 + 123
- * char = r mod 64 + 32
- */
- /***********************************************************************/
-